
#ifndef  LOG_H
#define  LOG_H

#include <memory>
#include "ILog.h"

class Topic;

class LogSize : public ILogSize {
public:
    LogSize(IMeta & meta);
    ~LogSize() override;

    size_t value() const override ;
    void value(size_t size) override ;

    ILogSize & overwrite(size_t fileSize) override ;

    recovery::Status sync() override;

private:
    IMeta & _meta;
};

namespace recovery {
namespace fs {
namespace file {
    class FileLogOperation;
} // end namespace file
} // end namespace fs
} // end namespace recovery

class Meta : public IMeta {
public:
	Meta(Topic & topic);
	~Meta() override ;

    recovery::Status open() override;
    recovery::Status close() override;
	bool isOpen() override { return _opened; }

	recovery::Status reset() override;

    //can run mulit-times
	recovery::Status load() override ;
	recovery::Status sync() override ;

    size_t size() const override;

	ILogSize & logSize() const override {
		return *_logSize;
	}

private:
	Topic & _topic;
	ILogSize * _logSize;
    std::unique_ptr<recovery::fs::file::FileLogOperation> _file;
	bool _opened = false;
};


class Log : public ILog {
public:
	Log(Topic & topic);
    ~Log() override;

	recovery::Status open() override ;
	recovery::Status close() override ;
	recovery::Status append(const std::string & data, size_t & appendedBytes) override ;
    recovery::Status sync() override ;
    recovery::Status truncate(size_t size) override ;

    recovery::Status size(size_t & size) const override ;

    IMeta & meta() override{ return *_meta; }

private:
	Topic & _topic;
	IMeta * _meta;
    std::unique_ptr<recovery::fs::file::FileLogOperation> _log;
};


#endif   /* LOG_H */
